#region Copyright(c) 2006 ZO, All right reserved.
// -----------------------------------------------------------------------------
// Copyright(c) 2006 ZO, All right reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   1.  Redistribution of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//   2.  Redistribution in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//   3.  The name of the author may not be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// -----------------------------------------------------------------------------
#endregion


#region Using directives

using System;
using ZO.SmartCore.Collections.Generic;
using ZO.SmartCore.Core;

#endregion

namespace ZO.SmartMessenger.Plugins
{
    /// <summary>
    /// Represent a List of Protocol Plugin
    /// </summary>
    public sealed class ProtocolPluginCollection : OrderedDictionary<Guid, ProtocolPlugin>, IDisposable
    {

        #region Constructors

        #endregion

        #region Destructor

        #endregion

        #region Fields

        #endregion

        #region Events
        /// <summary>
        /// Occurs when the ProtocolPlugin is Connected.
        /// </summary>
        public static event EventHandler ProtocolPluginConnectCompleted;

        /// <summary>
        /// Occurs when the ProtocolPlugin is Connecting.
        /// </summary>
        public static event EventHandler ProtocolPluginConnecting;


        /// <summary>
        /// Occurs on any error in Protocol.
        /// </summary>
        public static event EventHandler<ExceptionEventArgs> ProtocolPluginError;
        #endregion

        #region Operators

        #endregion

        #region Properties

        #endregion

        #region Methods

        /// <summary>
        /// Adds an element with the provided key and value to the
        /// <see cref="System.Collections.Generic.IDictionary{TKey, TValue}"></see>.
        /// </summary>
        /// <param name="key">The object to use as the key of the element to add.</param>
        /// <param name="value">The object to use as the value of the element to add.</param>
        /// <exception cref="System.NotSupportedException">The
        /// <see cref="System.Collections.Generic.IDictionary{TKey, TValue}"></see>
        /// is read-only.</exception>
        /// <exception cref="System.ArgumentException">An element with the
        /// same key already exists in the
        /// <see cref="System.Collections.Generic.IDictionary{TKey, TValue}"></see>.</exception>
        /// <exception cref="System.ArgumentNullException">key is null.</exception>
        public override void Add(Guid key, ProtocolPlugin value)
        {
            if (!Contains(key))
            {
                base.Add(key, value);

                value.Connecting += new EventHandler(ProtocolPlugin_Connecting);

                value.ConnectCompleted += new EventHandler(ProtocolPlugin_ConnectCompleted);

                value.Error += new EventHandler<ExceptionEventArgs>(ProtocolPlugin_Error);
            }
        }


        /// <summary>
        /// Handles the Connecting event of the ProtocolPlugin control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
        private void ProtocolPlugin_Connecting(object sender, EventArgs e)
        {
            if (ProtocolPluginConnecting != null)
            {
                ProtocolPluginConnecting(sender, e);
            }
        }

        /// <summary>
        /// Handles the Disconnecting event of the ProtocolPlugin control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
        private void ProtocolPlugin_ConnectCompleted(object sender, EventArgs e)
        {
            if (ProtocolPluginConnectCompleted != null)
            {
                ProtocolPluginConnectCompleted(sender, e);
            }
        }

        /// <summary>
        /// Handles the Error event of the ProtocolPlugin control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="T:SmartCore.Core.ExceptionEventArgs"/> instance containing the event data.</param>
        private void ProtocolPlugin_Error(object sender, ExceptionEventArgs e)
        {
            if (ProtocolPluginError != null)
            {
                ProtocolPluginError(sender, e);
            }
        }


        /// <summary>
        /// Removes the element with the specified key from the <see cref="System.Collections.Generic.IDictionary{TKey, TValue}"></see>.
        /// </summary>
        /// <param name="key">The key of the element to remove.</param>
        /// <returns>
        /// true if the element is successfully removed; otherwise, false.  This method also returns false if key was not found in the original <see cref="System.Collections.Generic.IDictionary{TKey, TValue}"></see>.
        /// </returns>
        /// <exception cref="System.NotSupportedException">The <see cref="System.Collections.Generic.IDictionary{TKey, TValue}"></see> is read-only.</exception>
        /// <exception cref="System.ArgumentNullException">key is null.</exception>
        public override bool Remove(Guid key)
        {
            if (Contains(key))
            {
                ProtocolPlugin value = this[key];

                if (value != null)
                {
                    value.Connecting -= new EventHandler(ProtocolPlugin_ConnectCompleted);
                    value.ConnectCompleted -= new EventHandler(ProtocolPlugin_ConnectCompleted);

                    value.Error -= new EventHandler<ExceptionEventArgs>(ProtocolPlugin_Error);

                }
                return base.Remove(key);

            }

            return false;
        }



        #endregion

        #region IDisposable Members

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            foreach (ProtocolPlugin var in Values)
            {
                var.Dispose();
            }
            GC.SuppressFinalize(this);
        }

        #endregion
    }
}
